/*
    获取access_token
    唯一，有效期2小时，提前5分钟请求
    每天调用2000次
    请求地址：https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET
    设计思想：
        1. 首次本地没有，发送请求获取acess_token，保存下来（本地文件）
        2. 第二次以后
            - 先去本地读取文件，判断它是否过期(isValidAccessToken)
                - 过期
                    - 重新请求token(getAccessToken)，保存覆盖原来的文件（保证文件是唯一的）(saveAccessToken)
                - 没有过期
                    - 直接使用

    整体思路：
        读取本地文件（readAccessToken）
            - 本地有文件
                - 判断它是否过期(isValidAccessToken)

                  - 过期了
                     - 重新请求token(getAccessToken)，保存覆盖原来的文件（保证文件是唯一的）(saveAccessToken)
                  - 没有过期
                     - 直接使用
             - 本地有文件
                - 发送请求获取access_token(getAccessToken), 保存下来（本地文件）（saveAccessToken），直接使用

 */



// 引入config文件
const{appID, appsecret} = require('../config');

console.log(appID, appsecret);

// 只要引入request-promise-native
const rp = require('request-promise-native');

// 引入fs模块(异步的)
const {writeFile, readFile} = require('../config');

//定义类，获取accesstoken
class Wechat{
    constructor(){

    }
    /**
     * 用来获取token
     *
     */
    getAccessToken(){

        // 定义请求地址
        const url = `https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=${appID}&secret=${appsecret}`


        return new Promise(resolve, reject) => {
            // 在服务器中进行请求，不能用ajax
            // request request-promise-native
            rp({
                method: 'GET',
                url, // 属性名和值的变量名相同，可以简写一个
                json: true
            }).then(res => {
                console.log(res);

                // 设置token的过期时间
                res.expires_in = Date.now() + (res.expires_in - 300) * 1000;

                // 想promise对象的状态改成成功的状态
                resolve(res);

            })
            .catch(err => {
                console.log(err)
                reject('getAccessToken方法除了问题：'+ err);
            })
        }


    }


    /**
     * 保存token的方法
     * @param accessToken 要保存的凭据
     */
    saveAccessToken(accessToken){
        // 将对象转化为json字符串
        accessToken = JSON.stringify(accessToken);

        return new Promise((resolve, reject) => {
            // 将token保存一个文件
            writeFile('./accessToken.txt', accessToken, err=>{
                if(!err){
                    console.log('文件保存成功~！');
                    resolve();
                }else{
                    reject('saveAccessToken方法出了问题:' + err);
                }
            })
        })
    }


    /**
     * 读取token的方法
     */
    saveAccessToken(accessToken){
        // 读取本地文件中的access_token
        return new Promise((resolve, reject) => {
            // 将token保存一个文件
            readFile('./accessToken.txt', (err, data) => {
                if(!err){
                    console.log('文件读取成功~！');
                    // 将json字符串转化为js对象
                    data = JSON.parse(data);
                    resolve(data);
                }else{
                    reject('saveAccessToken方法出了问题:' + err);
                }
            })
        })
    }

    /**
     * 判断token是否有效
     * @param data
     */
    isValidAccessToken(data){
        // 检测传入的参数是否有效
        if(!data && data.access_token && !data.expires_in){
            // 代表access_token无效的
            return false;
        }

        // 检测access_token是否在有效期内
        // if(data.expires_in < Date.now()){
        //     // 过期了
        //     return false;
        // }else{
        //     return true;
        // }
        // if else 代替简写方式
        return data.expires_in < Date.now();

    }




}


// 模拟测试
const w = new Wechat();
w.getAccessToken();

new Promise((resove, reject) => {
    w.read()
        .then(res => {
            // 本地有文件
            // 判断它是否过期
            if(w.isValidAccessToken(res)){
                // 有效的
                resolve(res);
            }else{
                // 本地没有文件
                w.getAccessToken()
                    .then(res => {
                        //保存下来（本地文件）（saveAccessToken），直接使用
                        w.saveAccessToken(res)
                            .then(() => {
                                resolve(res);
                            })
                    })
            }
        })
        .catch(err => {
            // 本地没有文件
            w.getAccessToken()
                .then(res => {
                    //保存下来（本地文件）（saveAccessToken），直接使用
                    w.saveAccessToken(res)
                        .then(() => {
                            resolve(res);
                        })
                })
        })
}).then(res => {
    console.log(res);
})

